/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package persistencia;

import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javabeans.EnumTipoProyeccion.TipoProyeccion;
import javabeans.JBCine;
import javabeans.JBCliente;
import javabeans.JBFuncion;
import javabeans.JBPelicula;
import javabeans.JBReserva;
import javabeans.JBSala;
import javabeans.JBTipoEntrada;
import javabeans.JBUsuario;
import javax.servlet.ServletContext;

/**
 *
 * @author Administrador
 */
public class Sistema implements ISistema {

    // <editor-fold defaultstate="collapsed" desc="private atributes">
    private Connection connection;
    private static Sistema instance = null;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="constructor">
    public static Sistema getInstance(ServletContext context) {
        if (instance == null) {
            instance = new Sistema(context);
        }
        return instance;
    }

    private Sistema(ServletContext context) {
        String conn = context.getInitParameter("connStr");
        String user = context.getInitParameter("user");
        String pass = context.getInitParameter("password");
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(conn, user, pass);

        } catch (SQLException ex) {
            Logger.getLogger(Sistema.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Sistema.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="private methods">
    //Se obtiene el ultimo id generado por la tabla
    private int selectLasIdFromDB(String table) throws SQLException {
        int id = 0;
        try {
            Statement st = connection.createStatement();
            //PreparedStatement ps = connection.prepareStatement("SELECT LAST_INSERT_ID() as id");
            ResultSet rs = st.executeQuery("SELECT id from " + table + " ORDER BY id DESC LIMIT 1");
            if (rs.next()) {
                id = rs.getInt("id");
            }
        } catch (SQLException exc) {
            throw exc;
        }
        return id;
    }
    
    //Obtiene las funciones de una pelicula
    private List<JBFuncion> obtenerFuncionesPorPelicula(int idPelicula) {
        List<JBFuncion> funciones = new LinkedList<JBFuncion>();

        try {
            PreparedStatement psFuncion = connection.prepareStatement("SELECT * FROM funciones WHERE peliculaId = ?");
            psFuncion.setInt(1, idPelicula);
            ResultSet rs = psFuncion.executeQuery();
            while (rs.next()) {
                JBFuncion f = new JBFuncion();
                f.setId(rs.getInt("id"));
                f.setHora(rs.getInt("hora"));
                f.setMinutos(rs.getInt("minutos"));
                f.setFecha(rs.getDate("fecha"));
                f.setDuracion(rs.getInt("duracion"));
                f.setCapacidad(rs.getInt("entradasDisponibles"));
                f.setSala(obtenerSala(rs.getInt("salaId")));
                f.setCine(obtenerCine(f.getSala().getCineId()));
                funciones.add(f);
            }
            psFuncion.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return funciones;
    }

    //Obtiene una funcion especifica
    private JBFuncion obtenerFuncionxId(int id) {
        JBFuncion f = new JBFuncion();
        try {
            PreparedStatement psFuncion = connection.prepareStatement("SELECT * FROM funciones WHERE id = ?");
            psFuncion.setInt(1, id);
            ResultSet rs = psFuncion.executeQuery();
            if (rs.next()) {
                f.setId(rs.getInt("id"));
                f.setHora(rs.getInt("hora"));
                f.setMinutos(rs.getInt("minutos"));
                f.setFecha(rs.getDate("fecha"));
                f.setDuracion(rs.getInt("duracion"));
                f.setCapacidad(rs.getInt("entradasDisponibles"));
                f.setSala(obtenerSala(rs.getInt("salaId")));
                f.setCine(obtenerCine(f.getSala().getCineId()));
            }
            psFuncion.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return f;
    }

    //Obtiene la lista de salas de acuerdo al cine
    private List<JBSala> obtenerSalas(int cineId) {
        List<JBSala> salas = new LinkedList<JBSala>();

        try {
            PreparedStatement psSala = connection.prepareStatement("SELECT * FROM salas WHERE cineId = ?");
            psSala.setInt(1, cineId);
            ResultSet rs = psSala.executeQuery();
            while (rs.next()) {
                JBSala sala = new JBSala();
                sala.setId(rs.getInt("id"));
                sala.setCineId(rs.getInt("cineId"));
                sala.setNumero(rs.getInt("numero"));
                sala.setCapacidad(rs.getInt("capacidad"));
                int proy = rs.getInt("proyeccion");
                if (proy == TipoProyeccion.proyeccion2D.ordinal()) {
                    sala.setTipoProyeccion(TipoProyeccion.proyeccion2D);
                } else {
                    sala.setTipoProyeccion(TipoProyeccion.proyeccion3D);
                }
                salas.add(sala);
            }
            psSala.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return salas;
    }

    //Obtiene los datos de una sala especifica
    private JBSala obtenerSala(int salaId) {
        JBSala sala = new JBSala();

        try {
            PreparedStatement psSala = connection.prepareStatement("SELECT * FROM salas WHERE id = ?");
            psSala.setInt(1, salaId);
            ResultSet rs = psSala.executeQuery();
            if (rs.next()) {
                sala.setId(rs.getInt("id"));
                sala.setCineId(rs.getInt("cineId"));
                sala.setNumero(rs.getInt("numero"));
                sala.setCapacidad(rs.getInt("capacidad"));
                int proy = rs.getInt("proyeccion");
                if (proy == TipoProyeccion.proyeccion2D.ordinal()) {
                    sala.setTipoProyeccion(TipoProyeccion.proyeccion2D);
                } else {
                    sala.setTipoProyeccion(TipoProyeccion.proyeccion3D);
                }
            }
            psSala.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return sala;
    }

    //Obtiene los datos de un usuario especifico
    private JBUsuario obtenerUsuarioxCI(int ci) throws SQLException {
        JBUsuario usuario = new JBUsuario();
        try {

            PreparedStatement st = connection.prepareStatement("SELECT * FROM usuarios WHERE ci = ?");

            st.setInt(1, ci);

            ResultSet rs = st.executeQuery();

            if (rs.next()) {

                usuario.setCi(ci);
                usuario.setUsuario(rs.getString("usuario"));
                usuario.setPassword(rs.getString("password"));
                usuario.setTipoUsuario(rs.getString("tipousuario"));
            }

        } catch (SQLException ex) {
            throw ex;
        }
        return usuario;
    }
    
    //Obtiene los tipos de entradas para las reservas
    private List<JBTipoEntrada> obtenerTiposEntradasReserva(int idReserva) throws SQLException {
        List<JBTipoEntrada> entradas = new LinkedList<JBTipoEntrada>();
        try {
            PreparedStatement ps = connection.prepareStatement("SELECT id, precio, cantidad FROM tiposentradas t INNER JOIN reservatipoentrada rt ON t.id = rt.idTipoEntrada WHERE idReserva = ?");
            ps.setInt(1, idReserva);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                JBTipoEntrada e = new JBTipoEntrada();
                e.setTipoEntrada(rs.getInt("id"));
                e.setPrecio(rs.getDouble("precio"));
                e.setCantidad(rs.getInt("cantidad"));
                entradas.add(e);
            }
        } catch (SQLException exc) {
            throw exc;
        }
        return entradas;
    }
    
    public JBPelicula obtenerPeliculaxFuncion(int idFuncion) throws SQLException {
        JBPelicula p = new JBPelicula();

        try {
            PreparedStatement ps = connection.prepareStatement("SELECT p.* FROM peliculas p INNER JOIN "
                    + "funciones f ON p.id = f.peliculaId WHERE f.id = ? GROUP BY p.id");
            ps.setInt(1, idFuncion);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                p.setId(rs.getInt("id"));
                p.setNombre(rs.getString("nombre"));
                p.setDescripcion(rs.getString("descripcion"));
                p.setEdad(rs.getInt("edadApta"));
                p.setEdadApta(p.getEdad());
                p.setFechaEstreno(rs.getDate("fechaEstreno"));
                p.setTipoProyeccion(rs.getInt("proyeccion"));
                p.setIdioma(rs.getInt("idioma"));
                p.setDirector(rs.getString("director"));
                p.setActores(rs.getString("actores"));
                p.setListaFunciones(obtenerFuncionesPorPelicula(p.getId()));
            }
            ps.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return p;
    }

    private List<JBReserva> obtenerReservasActivasCliente(int ci) throws SQLException {
        List<JBReserva> reservas = new LinkedList<JBReserva>();
        try {
            PreparedStatement ps = connection.prepareStatement("SELECT * FROM reservas WHERE ci = ? AND cancelada = ?");
            ps.setInt(1, ci);
            ps.setBoolean(2, false);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                JBReserva r = new JBReserva();
                r.setId(rs.getInt("id"));
                r.setFecha(rs.getDate("fecha"));
                r.setCostoTotal(rs.getDouble("costoTotal"));
                int cancelada = rs.getInt("cancelada");
                r.setCancelada(cancelada == 0 ? false : true);
                int vendida = rs.getInt("vendida");
                r.setVendida(vendida == 0 ? false : true);
                r.setFuncion(obtenerFuncionxId(rs.getInt("idFuncion")));
                r.setTiposEntradas(obtenerTiposEntradasReserva(r.getId()));
                r.setPelicula(obtenerPeliculaxFuncion(r.getFuncion().getId()));
                reservas.add(r);
            }
        } catch (SQLException exc) {
            throw exc;
        }
        return reservas;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="public methods">
    //Se utiliza para convertir una una fecha con tipo String a Date
    @Override
    public Date StringToDate(String fechaString, int horas, int minutos) throws ParseException {
        Date fecha;
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm");
        try {
            fecha = df.parse(fechaString);
            /*if (!df.format(fecha).equals(fechaString)) {
            fecha = null;
            } else {*/
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(fecha);
            calendar.add(Calendar.HOUR, horas);
            calendar.add(Calendar.MINUTE, minutos);
            fecha = calendar.getTime();
            //}

        } catch (ParseException exc) {
            throw exc;
        }
        return fecha;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="BD Methods">
    // <editor-fold defaultstate="collapsed" desc="Peliculas, Funciones, Cines y Salas">
    //Se utiliza para guardar una pelicula
    @Override
    public int salvarPelicula(JBPelicula pelicula) throws SQLException {
        int result = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO peliculas (nombre, descripcion, edadApta, fechaEstreno, proyeccion, idioma, director, actores) "
                    + " VALUES (?,?,?,?,?,?,?,?)");
            ps.setString(1, pelicula.getNombre());
            ps.setString(2, pelicula.getDescripcion());
            ps.setInt(3, pelicula.getEdad());
            ps.setDate(4, new java.sql.Date(pelicula.getFechaEstreno().getTime()));
            ps.setInt(5, pelicula.getTipoProyeccion().ordinal());
            ps.setInt(6, pelicula.getIdioma().ordinal());
            ps.setString(7, pelicula.getDirector());
            ps.setString(8, pelicula.getActores());
            result = ps.executeUpdate();
            ps.close();

        } catch (SQLException exc) {
            throw exc;
        }
        return result;
    }

    //Se utiliza para guardar una funcion
    @Override
    public int salvarFuncion(JBFuncion funcion, int peliculaId) throws SQLException {
        int resultado = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO funciones (fecha, hora, minutos, duracion, peliculaId, cineId, salaId, entradasDisponibles) "
                    + "VALUES (?,?,?,?,?,?,?,?)");

            ps.setDate(1, new java.sql.Date(funcion.getFecha().getTime()));
            ps.setInt(2, funcion.getHora());
            ps.setInt(3, funcion.getMinutos());
            ps.setInt(4, funcion.getDuracion());
            ps.setInt(5, peliculaId);
            ps.setInt(6, funcion.getCine().getId());
            ps.setInt(7, funcion.getSala().getId());
            ps.setInt(8, funcion.getSala().getCapacidad());
            resultado = ps.executeUpdate();
            ps.close();
            return resultado;
        } catch (SQLException exc) {
            throw exc;
        }
    }

    //Obtiene la lista de peliculas del sistema
    @Override
    public List<JBPelicula> listarPeliculas() throws SQLException {
        List<JBPelicula> peliculas = new LinkedList<JBPelicula>();

        try {
            Statement st = connection.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM peliculas");
            while (rs.next()) {
                JBPelicula p = new JBPelicula();
                p.setId(rs.getInt("id"));
                p.setNombre(rs.getString("nombre"));
                p.setDescripcion(rs.getString("descripcion"));
                p.setEdad(rs.getInt("edadApta"));
                p.setEdadApta(p.getEdad());
                p.setFechaEstreno(rs.getDate("fechaEstreno"));
                p.setTipoProyeccion(rs.getInt("proyeccion"));
                p.setIdioma(rs.getInt("idioma"));
                p.setDirector(rs.getString("director"));
                p.setActores(rs.getString("actores"));
                p.setListaFunciones(obtenerFuncionesPorPelicula(p.getId()));
                peliculas.add(p);
            }
            st.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return peliculas;
    }

    //Obtiene la lista de peliculas por cine
    @Override
    public List<JBPelicula> listarPeliculasxCine(int cineId) throws SQLException {
        List<JBPelicula> peliculas = new LinkedList<JBPelicula>();

        try {
            PreparedStatement ps = connection.prepareStatement("SELECT * FROM peliculas p INNER JOIN funciones f ON p.id = f.peliculaId WHERE cineId = ? GROUP BY p.id;");
            ps.setInt(1, cineId);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                JBPelicula p = new JBPelicula();
                p.setId(rs.getInt("id"));
                p.setNombre(rs.getString("nombre"));
                p.setDescripcion(rs.getString("descripcion"));
                p.setEdad(rs.getInt("edadApta"));
                p.setEdadApta(p.getEdad());
                p.setFechaEstreno(rs.getDate("fechaEstreno"));
                p.setTipoProyeccion(rs.getInt("proyeccion"));
                p.setIdioma(rs.getInt("idioma"));
                p.setDirector(rs.getString("director"));
                p.setActores(rs.getString("actores"));
                p.setListaFunciones(obtenerFuncionesPorPelicula(p.getId()));
                peliculas.add(p);
            }
            ps.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return peliculas;
    }

    //Obtiene la lista de peliculas que son estrenos
    @Override
    public List<JBPelicula> verEstrenos() throws SQLException {
        List<JBPelicula> peliculas = new LinkedList<JBPelicula>();

        try {
            Statement st = connection.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM peliculas where fechaEstreno > now()");
            while (rs.next()) {
                JBPelicula p = new JBPelicula();
                p.setId(rs.getInt("id"));
                p.setNombre(rs.getString("nombre"));
                p.setDescripcion(rs.getString("descripcion"));
                p.setEdad(rs.getInt("edadApta"));
                p.setEdadApta(p.getEdad());
                p.setFechaEstreno(rs.getDate("fechaEstreno"));
                p.setTipoProyeccion(rs.getInt("proyeccion"));
                p.setIdioma(rs.getInt("idioma"));
                p.setDirector(rs.getString("director"));
                p.setActores(rs.getString("actores"));
                p.setListaFunciones(obtenerFuncionesPorPelicula(p.getId()));
                peliculas.add(p);
            }
            st.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return peliculas;
    }

    
    //Obtiene la lista de peliculas en cartelera
    @Override
    public List<JBPelicula> verCartelera() throws SQLException {
        List<JBPelicula> peliculas = new LinkedList<JBPelicula>();

        try {
            Statement st = connection.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM peliculas where fechaEstreno < now()");
            while (rs.next()) {
                JBPelicula p = new JBPelicula();
                p.setId(rs.getInt("id"));
                p.setNombre(rs.getString("nombre"));
                p.setDescripcion(rs.getString("descripcion"));
                p.setEdad(rs.getInt("edadApta"));
                p.setEdadApta(p.getEdad());
                p.setFechaEstreno(rs.getDate("fechaEstreno"));
                p.setTipoProyeccion(rs.getInt("proyeccion"));
                p.setIdioma(rs.getInt("idioma"));
                p.setDirector(rs.getString("director"));
                p.setActores(rs.getString("actores"));
                p.setListaFunciones(obtenerFuncionesPorPelicula(p.getId()));
                peliculas.add(p);
            }
            st.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return peliculas;
    }

    //Obtiene los datos de una pelicula a partir del id
    @Override
    public JBPelicula obtenerPelicula(int id) throws SQLException {
        JBPelicula p = new JBPelicula();
        try {
            PreparedStatement ps = connection.prepareStatement("SELECT * FROM peliculas WHERE id = ?");
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                p.setId(rs.getInt("id"));
                p.setNombre(rs.getString("nombre"));
                p.setDescripcion(rs.getString("descripcion"));
                p.setEdad(rs.getInt("edadApta"));
                p.setEdadApta(p.getEdad());
                p.setFechaEstreno(rs.getDate("fechaEstreno"));
                p.setTipoProyeccion(rs.getInt("proyeccion"));
                p.setIdioma(rs.getInt("idioma"));
                p.setDirector(rs.getString("director"));
                p.setActores(rs.getString("actores"));
                p.setListaFunciones(obtenerFuncionesPorPelicula(id));
            }
            ps.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return p;
    }

    //Obtiene la lista de cines
    @Override
    public List<JBCine> listarCines() throws SQLException {
        List<JBCine> cines = new LinkedList<JBCine>();

        try {
            Statement st = connection.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM cines");
            while (rs.next()) {
                JBCine cine = new JBCine();
                cine.setId(rs.getInt("id"));
                cine.setNombre(rs.getString("nombre"));
                cine.setDireccion(rs.getString("direccion"));
                cine.setCiudad(rs.getString("ciudad"));
                cine.setEncargado(rs.getString("encargado"));
                cine.setSalas(obtenerSalas(cine.getId()));
                cines.add(cine);
            }
            st.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return cines;
    }

    //Obtiene los datos de un cine de acuerdo a su id
    @Override
    public JBCine obtenerCine(int cineId) throws SQLException {
        JBCine cine = new JBCine();

        try {
            PreparedStatement psCine = connection.prepareStatement("SELECT * FROM cines WHERE id = ?");
            psCine.setInt(1, cineId);
            ResultSet rs = psCine.executeQuery();
            if (rs.next()) {
                cine.setId(rs.getInt("id"));
                cine.setNombre(rs.getString("nombre"));
                cine.setDireccion(rs.getString("direccion"));
                cine.setCiudad(rs.getString("ciudad"));
                cine.setEncargado(rs.getString("encargado"));
                cine.setSalas(obtenerSalas(cine.getId()));
            }
            psCine.close();
            rs.close();
        } catch (SQLException exc) {
            exc.toString();
        }
        return cine;
    }
    
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Clientes y Usuarios">
    //Se utiliza para crear el cliente
    @Override
    public JBUsuario crearCliente(JBCliente cliente) throws SQLException {

        try {
            PreparedStatement psCliente = connection.prepareStatement("INSERT INTO clientes (ci, nombre, nacimiento, email)VALUES (?,?,?,?)");

            psCliente.setInt(1, cliente.getCi());
            psCliente.setString(2, cliente.getNombre());
            psCliente.setDate(3, new java.sql.Date(cliente.getFechaNacimiento().getTime()));
            psCliente.setString(4, cliente.getEmail());

            int result = psCliente.executeUpdate();

            if (result > 0) {
                PreparedStatement psUsuario = connection.prepareStatement("INSERT INTO usuarios (ci, usuario, password, tipousuario)VALUES (?,?,?,?)");

                psUsuario.setInt(1, cliente.getCi());
                psUsuario.setString(2, cliente.getUsuario().getUsuario());
                psUsuario.setString(3, cliente.getUsuario().getPassword());
                psUsuario.setString(4, cliente.getUsuario().getTipoUsuario());

                int resultUsuario = psUsuario.executeUpdate();

                if (resultUsuario > 0) {

                    psCliente.close();

                    return cliente.getUsuario();
                }
            }
        } catch (SQLException exc) {
            throw exc;
        }
        return null;
    }

    //Se utiliza para verificar el inicio de sesion del usuario
    @Override
    public JBUsuario login(String usuario, String password) throws SQLException {

        try {

            PreparedStatement st = connection.prepareStatement("SELECT * FROM usuarios WHERE usuario = ? AND password = ?");

            st.setString(1, usuario);
            st.setString(2, password);

            ResultSet rs = st.executeQuery();

            JBUsuario user = new JBUsuario();

            if (rs.next()) {

                user.setCi(rs.getInt("ci"));
                user.setUsuario(rs.getString("usuario"));
                user.setPassword(rs.getString("password"));
                user.setTipoUsuario(rs.getString("tipousuario"));

                return user;
            }

        } catch (SQLException ex) {
            throw ex;
        }
        return null;
    }

    //Obtiene los datos del cliente a partir de su cedula
    @Override
    public JBCliente obtenerCliente(int ci) throws SQLException {
        JBCliente cliente = new JBCliente();
        try {
            PreparedStatement ps = connection.prepareStatement("SELECT * FROM clientes WHERE ci = ?");
            ps.setInt(1, ci);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                cliente.setCi(ci);
                cliente.setNombre(rs.getString("nombre"));
                cliente.setFechaNacimiento(rs.getDate("nacimiento"));
                cliente.setEmail(rs.getString("email"));
                cliente.setUsuario(obtenerUsuarioxCI(ci));
                cliente.setReservas(obtenerReservasActivasCliente(ci));
            }
        } catch (SQLException exc) {
            throw exc;
        }
        return cliente;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Reservas y Tipos de Entradas">
    //Crea la reserva para el cliente especificado
    @Override
    public int salvarReserva(JBReserva reserva, int ci) throws SQLException {
        int resultado = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO reservas (ci, fecha, costoTotal, cancelada, vendida, idFuncion) VALUES (?,?,?,?,?,?)");
            ps.setInt(1, ci);
            ps.setDate(2, new java.sql.Date(reserva.getFecha().getTime()));
            ps.setDouble(3, reserva.getCostoTotal());
            ps.setInt(4, (reserva.isCancelada() ? 1 : 0));
            ps.setInt(5, (reserva.isVendida() ? 1 : 0));
            ps.setInt(6, reserva.getFuncion().getId());
            resultado = ps.executeUpdate();
            if (resultado >= 1) {
                int resultadoInterno = 0;
                int idReserva = selectLasIdFromDB("reservas");
                for (JBTipoEntrada e : reserva.getTiposEntradas()) {
                    resultadoInterno = salvarTipoEntradaReservas(e, idReserva);
                    if (resultadoInterno <= 0) {
                        return resultadoInterno;
                    }
                }
            }
            ps.close();
        } catch (SQLException exc) {
            throw exc;
        }
        return resultado;
    }
    //Ingresa al sistema los tipos de reservas
    private int salvarTipoEntradaReservas(JBTipoEntrada entrada, int idReserva) throws SQLException {
        int resultado = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO reservatipoentrada (idTipoEntrada, idReserva, cantidad) "
                    + "VALUES (?,?,?)");
            ps.setInt(1, entrada.getTipoEntrada().ordinal());
            ps.setInt(2, idReserva);
            ps.setInt(3, entrada.getCantidad());

            resultado = ps.executeUpdate();
        } catch (SQLException exc) {
            throw exc;
        }
        return resultado;
    }

    @Override
    public List<JBReserva> obtenerReservas(int ci, Date fechaSistema) throws SQLException {
        List<JBReserva> reservasActivas = new LinkedList<JBReserva>();
        try {
            List<JBReserva> reservas = new LinkedList<JBReserva>();
            reservas = obtenerReservasActivasCliente(ci);
            for (JBReserva r : reservas) {
                if (r.getFuncion().getFecha().after(fechaSistema)) {
                    cancelarReserva(r);
                } else {
                    reservasActivas.add(r);
                }
            }
            return reservasActivas;

        } catch (SQLException exc) {
            throw exc;
        }

    }

    private int cancelarReserva(JBReserva reserva) throws SQLException {
        int resultado = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("UPDATE reservas SET cancelada = ? WHERE id = ?");
            ps.setInt(1, 1);
            ps.setInt(2, reserva.getId());
            resultado = ps.executeUpdate();
        } catch (SQLException exc) {
            throw exc;
        }
        return resultado;
    }
    
    @Override
    public int restarCapacidadSala(JBFuncion funcion, int cant) throws SQLException{
        int resultado = 0;
        try {
            PreparedStatement ps = connection.prepareStatement("UPDATE funciones SET entradasDisponibles = ? WHERE id = ?");
            ps.setInt(1, cant);
            ps.setInt(2, funcion.getId());
            resultado = ps.executeUpdate();
        } catch (SQLException exc) {
            throw exc;
        }
        return resultado;
    }
    // </editor-fold>
    // </editor-fold>
}
